package com.schoolhelper.task.service.impl;

import com.schoolhelper.task.domain.TaskOrder;
import com.schoolhelper.task.mapper.TaskOrderMapper;
import com.schoolhelper.task.service.TaskOrderService;
import com.schoolhelper.notification.service.NotificationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;

/**
 * 任务订单服务层实现类
 * 实现任务订单相关的业务逻辑
 */
@Service
@Transactional
public class TaskOrderServiceImpl implements TaskOrderService {
    
    private static final Logger logger = LoggerFactory.getLogger(TaskOrderServiceImpl.class);
    
    // 任务订单状态常量
    private static final String STATUS_OPEN = "OPEN";
    private static final String STATUS_ACCEPTED = "ACCEPTED";
    private static final String STATUS_COMPLETED = "COMPLETED";
    private static final String STATUS_CANCELLED = "CANCELLED";
    private static final String STATUS_TIMEOUT = "TIMEOUT";
    
    @Autowired
    private TaskOrderMapper taskOrderMapper;
    
    @Autowired
    private NotificationService notificationService;
    
    /**
     * 创建新的任务订单
     * @param taskOrder 任务订单对象
     * @return 创建成功的任务订单
     */
    @Override
    public TaskOrder createTaskOrder(TaskOrder taskOrder) {
        // 设置默认状态和时间
        taskOrder.setStatus(STATUS_OPEN);
        taskOrder.setCreatedTime(LocalDateTime.now());
        taskOrder.setUpdatedTime(LocalDateTime.now());
        
        // 插入数据库
        logger.info("创建新任务订单 - title={}, category={}, publisherId={}", 
                   taskOrder.getTitle(), taskOrder.getCategory(), taskOrder.getPublisherId());
        
        int result = taskOrderMapper.insertTaskOrder(taskOrder);
        if (result > 0) {
            logger.info("任务订单创建成功 - id={}, title={}", taskOrder.getId(), taskOrder.getTitle());
            return taskOrder;
        }
        
        logger.error("任务订单创建失败 - affectedRows={}", result);
        throw new RuntimeException("创建任务订单失败");
    }
    
    /**
     * 根据ID获取任务订单详情
     * @param id 订单ID
     * @return 任务订单对象
     */
    @Override
    @Transactional(readOnly = true)
    public TaskOrder getTaskOrderById(Long id) {
        if (id == null) {
            throw new IllegalArgumentException("订单ID不能为空");
        }
        TaskOrder taskOrder = taskOrderMapper.selectTaskOrderById(id);
        if (taskOrder == null) {
            throw new RuntimeException("任务订单不存在");
        }
        return taskOrder;
    }
    
    /**
     * 获取所有任务订单列表
     * @return 任务订单列表
     */
    @Override
    @Transactional(readOnly = true)
    public List<TaskOrder> getAllTaskOrders() {
        return taskOrderMapper.selectAllTaskOrders();
    }
    
    /**
     * 根据状态获取任务订单列表
     * @param status 订单状态
     * @return 任务订单列表
     */
    @Override
    @Transactional(readOnly = true)
    public List<TaskOrder> getTaskOrdersByStatus(String status) {
        if (status == null || status.trim().isEmpty()) {
            throw new IllegalArgumentException("状态不能为空");
        }
        return taskOrderMapper.selectTaskOrdersByStatus(status);
    }
    
    /**
     * 获取用户发布的任务订单列表
     * @param publisherId 发布者用户ID
     * @return 任务订单列表
     */
    @Override
    @Transactional(readOnly = true)
    public List<TaskOrder> getMyPublishedOrders(Long publisherId) {
        if (publisherId == null) {
            throw new IllegalArgumentException("发布者ID不能为空");
        }
        return taskOrderMapper.selectTaskOrdersByPublisherId(publisherId);
    }
    
    /**
     * 获取用户接受的任务订单列表
     * @param accepterId 接单者用户ID
     * @return 任务订单列表
     */
    @Override
    @Transactional(readOnly = true)
    public List<TaskOrder> getMyAcceptedOrders(Long accepterId) {
        if (accepterId == null) {
            throw new IllegalArgumentException("接单者ID不能为空");
        }
        return taskOrderMapper.selectTaskOrdersByAccepterId(accepterId);
    }
    
    /**
     * 根据分类获取任务订单列表
     * @param category 任务分类
     * @return 任务订单列表
     */
    @Override
    @Transactional(readOnly = true)
    public List<TaskOrder> getTaskOrdersByCategory(String category) {
        if (category == null || category.trim().isEmpty()) {
            throw new IllegalArgumentException("分类不能为空");
        }
        return taskOrderMapper.selectTaskOrdersByCategory(category);
    }
    
    /**
     * 接受任务订单
     * @param orderId 订单ID
     * @param accepterId 接单者用户ID
     * @return 是否接单成功
     */
    @Override
    public boolean acceptTaskOrder(Long orderId, Long accepterId) {
        if (orderId == null || accepterId == null) {
            throw new IllegalArgumentException("订单ID和接单者ID不能为空");
        }
        
        // 检查订单是否存在且状态为OPEN
        TaskOrder taskOrder = taskOrderMapper.selectTaskOrderById(orderId);
        if (taskOrder == null) {
            throw new RuntimeException("任务订单不存在");
        }
        // 验证任务订单状态
        if (!STATUS_OPEN.equals(taskOrder.getStatus())) {
            logger.warn("尝试接单失败 - 订单状态不正确: orderId={}, status={}", orderId, taskOrder.getStatus());
            throw new RuntimeException("该任务订单已被接受或已完成");
        }
        
        // 验证发布者信息完整性
        if (taskOrder.getPublisherId() == null) {
            logger.error("数据完整性错误 - 任务发布者ID为空: orderId={}", orderId);
            throw new RuntimeException("任务发布者信息异常");
        }
        
        // 验证不能接受自己发布的任务
        if (Objects.equals(taskOrder.getPublisherId(), accepterId)) {
            logger.warn("业务规则违反 - 尝试接受自己发布的任务: orderId={}, publisherId={}, accepterId={}", 
                       orderId, taskOrder.getPublisherId(), accepterId);
            throw new RuntimeException("不能接受自己发布的任务");
        }
        
        // 更新订单状态
        logger.info("开始接单操作 - orderId={}, accepterId={}, publisherId={}", 
                   orderId, accepterId, taskOrder.getPublisherId());
        
        // 设置接单时间为当前时间
        String acceptedTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        int result = taskOrderMapper.updateTaskOrderStatus(orderId, STATUS_ACCEPTED, accepterId, acceptedTime);
        
        if (result <= 0) {
            logger.error("接单失败 - 数据库更新失败: orderId={}, affectedRows={}", orderId, result);
            throw new RuntimeException("数据库更新失败，影响行数: " + result);
        }
        
        logger.info("接单成功 - orderId={}, accepterId={}", orderId, accepterId);
        return true;
    }
    
    /**
     * 完成任务订单
     * @param orderId 订单ID
     * @param userId 操作用户ID（发布者或接单者）
     * @return 是否完成成功
     */
    @Override
    public boolean completeTaskOrder(Long orderId, Long userId) {
        if (orderId == null || userId == null) {
            throw new IllegalArgumentException("订单ID和用户ID不能为空");
        }
        
        // 检查订单是否存在且状态为ACCEPTED
        TaskOrder taskOrder = taskOrderMapper.selectTaskOrderById(orderId);
        if (taskOrder == null) {
            throw new RuntimeException("任务订单不存在");
        }
        if (!STATUS_ACCEPTED.equals(taskOrder.getStatus())) {
            throw new RuntimeException("该任务订单未被接受或已完成");
        }
        
        // 检查操作权限（发布者或接单者都可以标记完成）
        if (!taskOrder.getPublisherId().equals(userId) && !taskOrder.getAccepterId().equals(userId)) {
            throw new RuntimeException("无权限操作该任务订单");
        }
        
        // 更新订单状态
        logger.info("完成任务订单 - orderId={}, userId={}", orderId, userId);
        int result = taskOrderMapper.updateTaskOrderStatus(orderId, STATUS_COMPLETED, taskOrder.getAccepterId(), null);
        return result > 0;
    }
    
    /**
     * 取消任务订单
     * @param orderId 订单ID
     * @param userId 操作用户ID（只有发布者可以取消）
     * @return 是否取消成功
     */
    @Override
    public boolean cancelTaskOrder(Long orderId, Long userId) {
        if (orderId == null || userId == null) {
            throw new IllegalArgumentException("订单ID和用户ID不能为空");
        }
        
        // 检查订单是否存在
        TaskOrder taskOrder = taskOrderMapper.selectTaskOrderById(orderId);
        if (taskOrder == null) {
            throw new RuntimeException("任务订单不存在");
        }
        if (STATUS_COMPLETED.equals(taskOrder.getStatus()) || STATUS_CANCELLED.equals(taskOrder.getStatus())) {
            throw new RuntimeException("该任务订单已完成或已取消");
        }
        
        // 检查操作权限（只有发布者可以取消）
        if (!taskOrder.getPublisherId().equals(userId)) {
            throw new RuntimeException("只有发布者可以取消任务订单");
        }
        
        // 更新订单状态
        logger.info("取消任务订单 - orderId={}, userId={}", orderId, userId);
        int result = taskOrderMapper.updateTaskOrderStatus(orderId, STATUS_CANCELLED, taskOrder.getAccepterId(), null);
        return result > 0;
    }
    
    /**
     * 取消接单
     * @param orderId 订单ID
     * @param userId 操作用户ID（只有接单者可以取消接单）
     * @return 是否取消成功
     */
    @Override
    public boolean cancelAcceptTaskOrder(Long orderId, Long userId) {
        if (orderId == null || userId == null) {
            throw new IllegalArgumentException("订单ID和用户ID不能为空");
        }
        
        // 检查订单是否存在
        TaskOrder taskOrder = taskOrderMapper.selectTaskOrderById(orderId);
        if (taskOrder == null) {
            throw new RuntimeException("任务订单不存在");
        }
        
        // 只有已接单状态的任务才能取消接单
        if (!STATUS_ACCEPTED.equals(taskOrder.getStatus())) {
            throw new RuntimeException("只有已接单的任务才能取消接单");
        }
        
        // 检查是否为接单者
        if (!Objects.equals(taskOrder.getAccepterId(), userId)) {
            throw new RuntimeException("只有接单者可以取消接单");
        }
        
        // 将订单状态重置为待接单，清空接单者信息
        logger.info("取消接单 - orderId={}, userId={}", orderId, userId);
        int result = taskOrderMapper.updateTaskOrderStatus(orderId, STATUS_OPEN, null, null);
        return result > 0;
    }
    
    /**
     * 更新任务订单信息
     * @param taskOrder 任务订单对象
     * @param userId 操作用户ID（只有发布者可以修改）
     * @return 是否更新成功
     */
    @Override
    public boolean updateTaskOrder(TaskOrder taskOrder, Long userId) {
        if (taskOrder == null || taskOrder.getId() == null || userId == null) {
            throw new IllegalArgumentException("参数不能为空");
        }
        
        // 检查订单是否存在
        TaskOrder existingOrder = taskOrderMapper.selectTaskOrderById(taskOrder.getId());
        if (existingOrder == null) {
            throw new RuntimeException("任务订单不存在");
        }
        
        // 检查操作权限（只有发布者可以修改）
        if (!existingOrder.getPublisherId().equals(userId)) {
            throw new RuntimeException("只有发布者可以修改任务订单");
        }
        
        // 检查订单状态（只有OPEN状态的订单可以修改）
        if (!STATUS_OPEN.equals(existingOrder.getStatus())) {
            throw new RuntimeException("只有待接单状态的任务可以修改");
        }
        
        // 更新订单信息
        int result = taskOrderMapper.updateTaskOrder(taskOrder);
        return result > 0;
    }
    
    /**
     * 删除任务订单
     * @param orderId 订单ID
     * @param userId 操作用户ID（只有发布者可以删除）
     * @return 是否删除成功
     */
    @Override
    public boolean deleteTaskOrder(Long orderId, Long userId) {
        if (orderId == null || userId == null) {
            throw new IllegalArgumentException("订单ID和用户ID不能为空");
        }
        
        // 检查订单是否存在
        TaskOrder taskOrder = taskOrderMapper.selectTaskOrderById(orderId);
        if (taskOrder == null) {
            throw new RuntimeException("任务订单不存在");
        }
        
        // 检查操作权限（只有发布者可以删除）
        if (!taskOrder.getPublisherId().equals(userId)) {
            throw new RuntimeException("只有发布者可以删除任务订单");
        }
        
        // 检查订单状态（只有OPEN或CANCELLED状态的订单可以删除）
        if (STATUS_ACCEPTED.equals(taskOrder.getStatus()) || STATUS_COMPLETED.equals(taskOrder.getStatus())) {
            throw new RuntimeException("已接单或已完成的任务不能删除");
        }
        
        // 删除订单
        int result = taskOrderMapper.deleteTaskOrder(orderId);
        return result > 0;
    }
    
    /**
     * 搜索任务订单
     * @param keyword 搜索关键词
     * @return 任务订单列表
     */
    @Override
    @Transactional(readOnly = true)
    public List<TaskOrder> searchTaskOrders(String keyword) {
        if (keyword == null || keyword.trim().isEmpty()) {
            return getTaskOrdersByStatus(STATUS_OPEN);
        }
        return taskOrderMapper.searchTaskOrders(keyword.trim());
    }
    
    /**
     * 分页获取任务订单列表
     * @param page 页码（从1开始）
     * @param size 每页大小
     * @return 任务订单列表
     */
    @Override
    @Transactional(readOnly = true)
    public List<TaskOrder> getTaskOrdersWithPagination(int page, int size) {
        if (page < 1 || size < 1) {
            throw new IllegalArgumentException("页码和每页大小必须大于0");
        }
        int offset = (page - 1) * size;
        return taskOrderMapper.selectTaskOrdersWithPagination(offset, size);
    }
    
    /**
     * 获取任务订单总数
     * @return 总数
     */
    @Override
    @Transactional(readOnly = true)
    public int countTaskOrders() {
        return taskOrderMapper.countTaskOrders();
    }
    
    @Override
    @Transactional
    public int handleExpiredTasks() {
        logger.info("开始处理过期任务");
        
        // 获取待接单的过期任务列表，为发布者创建通知
        List<TaskOrder> expiredOpenTasks = taskOrderMapper.selectExpiredOpenTasks();
        for (TaskOrder task : expiredOpenTasks) {
            try {
                // 为发布者创建任务超时通知
                notificationService.createTaskNotification(
                    task.getPublisherId(),
                    "TASK_TIMEOUT",
                    "任务超时通知",
                    "您发布的任务《" + task.getTitle() + "》已超时，系统已自动取消",
                    task.getId(),
                    null
                );
                logger.info("为发布者创建任务超时通知 - taskId={}, publisherId={}", task.getId(), task.getPublisherId());
            } catch (Exception e) {
                logger.error("创建任务超时通知失败 - taskId={}, publisherId={}, error={}", 
                           task.getId(), task.getPublisherId(), e.getMessage());
            }
        }
        
        // 获取已接单但超时的任务列表，为接单者和发布者创建通知
        List<TaskOrder> expiredAcceptedTasks = taskOrderMapper.selectExpiredAcceptedTasks();
        for (TaskOrder task : expiredAcceptedTasks) {
            try {
                // 为接单者创建任务超时通知
                if (task.getAccepterId() != null) {
                    notificationService.createTaskNotification(
                        task.getAccepterId(),
                        "TASK_TIMEOUT",
                        "任务超时通知",
                        "您接单的任务《" + task.getTitle() + "》已超时，请及时处理",
                        task.getId(),
                        task.getPublisherId()
                    );
                    logger.info("为接单者创建任务超时通知 - taskId={}, accepterId={}", task.getId(), task.getAccepterId());
                }
                
                // 为发布者创建任务超时通知
                notificationService.createTaskNotification(
                    task.getPublisherId(),
                    "TASK_TIMEOUT",
                    "任务超时通知",
                    "您发布的任务《" + task.getTitle() + "》已被接单但超时未完成",
                    task.getId(),
                    task.getAccepterId()
                );
                logger.info("为发布者创建任务超时通知 - taskId={}, publisherId={}", task.getId(), task.getPublisherId());
            } catch (Exception e) {
                logger.error("创建任务超时通知失败 - taskId={}, error={}", task.getId(), e.getMessage());
            }
        }
        
        // 处理待接单的过期任务，状态更新为已取消
        int cancelledCount = taskOrderMapper.updateExpiredTasksStatus();
        logger.info("处理待接单过期任务完成，共取消了 {} 个任务", cancelledCount);
        
        // 处理已接单但超时的任务，状态更新为已超时
        int timeoutCount = taskOrderMapper.updateAcceptedExpiredTasksStatus();
        logger.info("处理已接单超时任务完成，共标记了 {} 个任务为超时", timeoutCount);
        
        int totalUpdated = cancelledCount + timeoutCount;
        logger.info("处理过期任务总计完成，共更新了 {} 个任务状态（取消：{}，超时：{}）", 
                   totalUpdated, cancelledCount, timeoutCount);
        
        return totalUpdated;
    }
}